package com.xnx3.kefu.core.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.xnx3.Log;
import com.xnx3.j2ee.util.CacheUtil;
import com.xnx3.j2ee.util.ConsoleUtil;
import com.xnx3.kefu.core.vo.MessageReceiveVO;
import com.xnx3.kefu.core.vo.bean.Message;
import io.netty.channel.Channel;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
 * 离线消息存储，当用户上线后再推送给用户。
 * @author 管雷鸣
 *
 */
public class OfflineMessageUtil {
	/*
	 * 记录具体的离线消息。 两个人的一对一消息记录。
	 * {receiveId} 接收消息的 userid
	 * {sendId} 发送消息的userid
	 * 
	 * value 缓存存储的是一个 List<Message>
	 */
	public static final String CACHE_CHAT_KEY = "kefu:message:offline:{receiveId}:{sendId}";
	
	/**
	 * 记录某个人，谁给他发过离线消息，给他发过离线消息的人userid 的列表
	 * {receiveId} 接收消息的 userid 
	 * 这个key对应的value，便是一个map，因为map有去重功能，往里写入可以自动去重  Map<String,Integer> map.key 是发送方的userid， map.value 是离线消息有多少条
	 */
	public static final String CACHE_USERLIST_KEY = "kefu:message:offline:list:{receiveId}";
	
	/**
	 * 存储离线消息
	 * @param message 要存储的离线消息
	 */
	public static void addOfflineMessage(MessageReceiveVO messageVO){
		Message message = MessageUtil.messageReceiveVOToMessage(messageVO);
		//记录消息主体
		String messageKey = CACHE_CHAT_KEY.replace("{receiveId}", message.getReceiveId()).replace("{sendId}", message.getSendId());
		//先取出之前存的消息
		List<Message> messageList = (List<Message>) CacheUtil.get(messageKey);
		if(messageList == null){
			messageList = new ArrayList<Message>();
		}
		if(messageList.size() < 200){
			messageList.add(message);
		}else{
			//每个用户发送的消息，只记录200条以内，超过200条，这个用户肯定是想搞破坏的
			ConsoleUtil.error("遇到想搞破坏的用户，离线消息已经发了达到200条。message:"+message.toString());
		}
		CacheUtil.set(messageKey, messageList);

		
		//记录给他发送消息的人
		String listKey = CACHE_USERLIST_KEY.replace("{receiveId}", message.getReceiveId());
		Map<String, Integer> map = (Map<String, Integer>) CacheUtil.get(listKey);
		if(map == null){
			map = new HashMap<String, Integer>();
		}
		map.put(message.getSendId(), 1);
		CacheUtil.set(listKey, map);
	}
	
	/**
	 * 根据接收方的userid，获取这个用户的所有离线消息，发送给这个用户
	 * @param receiveId 接收消息的用户的user.chatid
	 * @param receiveId这个人的socket 通道
	 */
	public static void sendOfflineMessage(String receiveId, Channel channel){
		//先获取有谁给他发消息了
		String listKey = CACHE_USERLIST_KEY.replace("{receiveId}", receiveId);
		Map<String, Integer> sendIdMap = (Map<String, Integer>) CacheUtil.get(listKey);
		if(sendIdMap == null){
			//他没有离线消息
			return;
		}
		
		
		/****** 有离线消息，那么吧所有离线消息都取出来，发出去 ******/
		//遍历，挨个chat取
		for(Map.Entry<String, Integer> entry : sendIdMap.entrySet()){
			String sendId = entry.getKey();
			
			//取出这个人发给此人的消息
			String messageKey = CACHE_CHAT_KEY.replace("{receiveId}", receiveId).replace("{sendId}", sendId);
			Object obj = CacheUtil.get(messageKey);
			if(obj == null) {
				continue;
			}
			List<Message> messageList = (List<Message>) obj;
			if(messageList.size() < 1){
				continue;
			}
			for (int i = 0; i < messageList.size(); i++) {
				Message message = messageList.get(i);
				SocketUtil.sendMessage(channel, message);
			}
			//删除缓存的跟这个人的离线消息
			CacheUtil.delete(messageKey);
		}
		
		//删除这个人的所有离线消息
		CacheUtil.delete(listKey);
	}
}
